package com.droid.customcalendar.cal.view;

import java.util.Date;
import java.util.Locale;

import android.content.Context;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.droid.customcalendar.cal.model.MonthCalendarDataGenerator;
import com.droid.customcalendar.cal.util.DateTimeUtils;

public class MonthView extends ViewGroup {

	private MonthCalendarDataGenerator monthDataGenerator;
	private OnDateSelectedListener dateSelectedListener;
	private Date minDate;
	private int extraDaysTextColor = Color.GRAY;
	
	public MonthView(Context context) {
		super(context);
		init();
	}

	public MonthView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	private void init() {
		monthDataGenerator = new MonthCalendarDataGenerator();
		refreshViews();
	}
	
	private void refreshViews() {
		removeAllViews();
		createMonthView();
	}
	
	protected void createMonthView() {
		int weeks = monthDataGenerator.getNumberOfWeeks();
		int days = MonthCalendarDataGenerator.NUMBER_OF_DAYS_FROM_WEEK;
		for (int w = 0; w < weeks; w++) {
			for (int d = 0; d < days; d++) {
				View cell = createCellView(w, d);
				cell.setOnClickListener(getCellClickListener(w, d));
				addView(cell);
			}
		}
	}
	
	OnClickListener getCellClickListener(final int i, final int j) {
		return new OnClickListener() {
			public void onClick(View v) {
				Date date = monthDataGenerator.getDate(i, j);
				if (dateSelectedListener != null) {
					dateSelectedListener.onDateSelected(date, v);
				}
			}
		};
	}
	
	protected View createCellView(int week, int day) {
		TextView cell =  new TextView(getContext());
		Date date = monthDataGenerator.getDate(week, day);
		String content = monthDataGenerator.formatDate(date);
		if (isExtraDay(date)) {
			cell.setTextColor(extraDaysTextColor);
		}
		if (minDate != null && date.before(minDate)) {
			cell.setEnabled(false);
		}
		cell.setText(content);
		cell.setGravity(Gravity.CENTER);
		return cell;
	}
	
	private boolean isExtraDay(Date date) {
		Locale locale = monthDataGenerator.getLocale();
		int year = monthDataGenerator.getYear();
		int month = monthDataGenerator.getCurrentMonth();
		Date startDate = DateTimeUtils.getDayFromMonth(locale, year, month, 1);
		Date endDate = DateTimeUtils.getDayFromMonth(locale, year, month, monthDataGenerator.getCurrentMonthDays());
		date = DateTimeUtils.removeTime(date, locale);
		return date.before(startDate) || date.after(endDate);
	}
	
	public void setExtraDaysTextColor(int textColor) {
		this.extraDaysTextColor = textColor;
		invalidate();
	}
	
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		super.onMeasure(widthMeasureSpec, heightMeasureSpec);
		int cellWidth = getMeasuredWidth() / MonthCalendarDataGenerator.NUMBER_OF_DAYS_FROM_WEEK;
		int cellHeight = getMeasuredHeight() / monthDataGenerator.getNumberOfWeeks();
		int count = getChildCount();
		for (int index = 0; index < count; index++) {
			View child = getChildAt(index);
			int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(cellWidth, MeasureSpec.EXACTLY);
			int childHeigthMeasureSpce = MeasureSpec.makeMeasureSpec(cellHeight, MeasureSpec.EXACTLY);
			child.measure(childWidthMeasureSpec, childHeigthMeasureSpce);
		}
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		int posX = 0;
		int posY = 0;
		int count = getChildCount();
		for (int index = 0; index < count; index++) {
			View child = getChildAt(index); 
			if (index % MonthCalendarDataGenerator.NUMBER_OF_DAYS_FROM_WEEK == 0 && index > 0) {
				posX = 0;
				posY += child.getMeasuredHeight();
			}
			child.layout(posX, posY, posX + child.getMeasuredWidth(), posY + child.getMeasuredHeight());
			posX += child.getMeasuredWidth();
		}
	}
	
	public void setIntervalBackgroundResource(Date startDate, Date endDate,	int backgroundResId) {
		chageMonthViews(startDate, endDate, backgroundResId, true);
	}
	
	public void setIntervalTextColor(Date startDate, Date endDate, int color) {
		chageMonthViews(startDate, endDate, color, false);
	}

	protected void chageMonthViews(Date startDate, Date endDate, int res, boolean isBackground) {
		int start = monthDataGenerator.getDatePosition(startDate);
		int end = monthDataGenerator.getDatePosition(endDate);
		for (int index = start; index < end + 1; index++) {
			TextView textView = (TextView) getChildAt(index);
			if (textView != null) {
				if (isBackground) {
					textView.setBackgroundResource(res);
				} else {
					textView.setTextColor(res);
				}
			}
		}
	}
	
	public void setLocale(Locale locale) {
		monthDataGenerator = new MonthCalendarDataGenerator(locale);
		invalidate();
	}
	
	public void setOnDateSelectedListener(OnDateSelectedListener listener) {
		dateSelectedListener = listener;
	}
	
	public void setMonthDataGenerator(MonthCalendarDataGenerator calendarDataGenerator) {
		this.monthDataGenerator = calendarDataGenerator;
		refreshViews();
	}
	
	public MonthCalendarDataGenerator getCalendarDataGenerator() {
		return monthDataGenerator;
	}
	
	public void setMinDate(Date minDate) {
		this.minDate = minDate;
		refreshViews();
	}

	public Date getMinDate() {
		return minDate;
	}

	public static interface OnDateSelectedListener {
		void onDateSelected(Date date, View selectedView);
	}

}
